package com.qiangesoft.datasourcembpd.utils;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.Collections;

/**
 * MybatisPlus代码生成器
 *
 * @author qiangesoft
 * @date 2024-03-12
 */
public class MybatisPlusGenerator {

    /**
     * 主方法
     *
     * @param args
     */
    public static void main(String[] args) {
        // 当前项目路径
        String projectPath = System.getProperty("user.dir") + "/boot-business-datasource";
        // 模块名
        String moduleName = "sys";
        // 表名
        String[] tableNames = {"sys_user"};

        // 代码生成器: 数据源配置
        AutoGenerator autoGenerator = new AutoGenerator(buildDataSourceConfig());
        // 全局配置
        autoGenerator.global(buildGlobalConfig(projectPath));
        // 包配置
        autoGenerator.packageInfo(buildPackageConfig(projectPath, moduleName));
        // 模板配置
        autoGenerator.template(buildTemplateConfig());
        // 自定义配置
//        autoGenerator.injection();
        // 策略配置
        autoGenerator.strategy(buildStrategyConfig(tableNames));
        // 使用Freemarker引擎模板，默认的是Velocity引擎模板(VelocityTemplateEngine)
        autoGenerator.execute(new FreemarkerTemplateEngine());
    }

    /**
     * 数据源配置
     *
     * @return
     */
    private static DataSourceConfig buildDataSourceConfig() {
        // 使用元数据查询的方式生成代码
        return new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/boot_codegen?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false",
                "root",
                "root")
//                .schema("boot_codegen")
//                .keyWordsHandler(new MySqlKeyWordsHandler())
                .build();
    }

    /**
     * 全局配置
     *
     * @return
     */
    private static GlobalConfig buildGlobalConfig(String projectPath) {
        return new GlobalConfig.Builder()
                // 文件重写
                .fileOverride()
                // 输出路径
                .outputDir(projectPath + "/src/main/java")
                // 作者
                .author("qiangesoft")
                // 开启swagger
//                .enableSwagger()
                // 日期类型
                .dateType(DateType.TIME_PACK)
                // 备注日期格式
                .commentDate("yyyy-MM-dd")
                // 禁止打开文件夹
                .disableOpenDir()
                .build();
    }

    /**
     * 包配置
     *
     * @return
     */
    private static PackageConfig buildPackageConfig(String projectPath, String moduleName) {
        return new PackageConfig.Builder()
                // 根包路径
                .parent("com.qiangesoft.datasource")
                // 模块名
//                .moduleName(moduleName)
                // 实体包名
                .entity("entity")
                // 业务接口包名
                .service("service")
                // 业务实现类包名
                .serviceImpl("service.impl")
                // mapper接口包名
                .mapper("mapper")
                // 接口包名
                .controller("controller")
                .pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper/"))
                .build();
    }

    /**
     * 模板配置
     *
     * @return
     */
    private static TemplateConfig buildTemplateConfig() {
        return new TemplateConfig.Builder()
                .disable(TemplateType.ENTITY)
                // 实体模板
                .entity("/templates/entity.java")
                // 业务接口模板
                .service("/templates/service.java")
                // 业务实现类模板
                .serviceImpl("/templates/serviceImpl.java")
                // mapper接口模板
                .mapper("/templates/mapper.java")
                // mapper.xml模板
                .mapperXml("/templates/mapper.xml")
                // 接口模板
                .controller("/templates/controller.java")
                .build();
    }

    /**
     * 策略配置
     *
     * @return
     */
    private static StrategyConfig buildStrategyConfig(String[] tableNames) {
        return new StrategyConfig.Builder()
                // 开启大写命名
                .enableCapitalMode()
                // 开启跳过视图
                .enableSkipView()
                // 禁用sql过滤
                .disableSqlFilter()
                // 表匹配
                .addInclude(tableNames)
                // 表前缀匹配
//                .addTablePrefix("t_", "c_")
                // 表后缀匹配
//                .addFieldSuffix("_flag")

                // 1.entity配置
                .entityBuilder()
                // 开启链式编程
                .enableChainModel()
                // 开启lombok
                .enableLombok()
                // 乐观锁字段
                .versionColumnName("version")
//                .versionPropertyName("version")
                // 逻辑删除字段
                .logicDeleteColumnName("deleted")
//                .logicDeletePropertyName("deleted")
                // 数据库表映射实体命名规则
                .naming(NamingStrategy.underline_to_camel)
                // 表字段策略
                .addTableFills(new Column("create_by", FieldFill.INSERT))
                .addTableFills(new Column("create_time", FieldFill.INSERT))
                .addTableFills(new Column("update_by", FieldFill.UPDATE))
                .addTableFills(new Column("update_time", FieldFill.UPDATE))
                // 全局主键类型
                .idType(IdType.AUTO)

                // 2.controller配置
                .controllerBuilder()
                // 开启驼峰转连字符
                .enableHyphenStyle()
                // 开启生成@RestController
                .enableRestStyle()

                // 3.service配置
                .serviceBuilder()

                // 4.mapper配置
                .mapperBuilder()
//                .enableMapperAnnotation()
                .build();
    }
}
